package demo;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.*;
import org.apache.curator.retry.RetryNTimes;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

public class TestZookeeper {

    CuratorFramework client;


    @Before
    public void test1() throws Exception{
        // 创建一个重试对象，设定其对 zookeeper的连接是 2秒重试一次，一共重试5次
        RetryPolicy retryPolicy = new RetryNTimes(5,2000);
        // 记住线索，顺藤摸瓜
        client = CuratorFrameworkFactory.newClient("hadoop11:2181,hadoop12:2181,hadoop13:2181",retryPolicy);
        client.start();

    }

    @Test
    public void test2() throws Exception{
        client.create().withMode(CreateMode.PERSISTENT).forPath("from_java","123".getBytes());
    }

    @Test
    public void test3() throws Exception {
        // rmr /test_node
        client.delete().deletingChildrenIfNeeded().forPath("/test_node");
    }

    @Test
    public void test4() throws Exception{
        // set /test_node2 "苦楚"
        client.setData().forPath("/test_node2","苦楚".getBytes());
    }

    @Test
    public void test5() throws Exception{
        // get /test_node2
        byte[] bytes = client.getData().forPath("/test_node2");
        String s = new String(bytes);
        System.out.println("/test_node2的内容是：" + s);
    }

    @Test
    public void test6() throws Exception{
        // ls /test_node2
        List<String> children = client.getChildren().forPath("/test_node2");
        System.out.println(children);

        // 查看每个 子节点的值
        for (String child : children) {
            byte[] bytes = client.getData().forPath("/test_node2/" + child);
            System.out.println(child + "的值是：" + new String(bytes));
        }
    }

    @Test
    public void test7() throws Exception{
        // get /test_node2  不看值，只看属性
        Stat stat = client.checkExists().forPath("/test_node2");
        if (stat != null){
            System.out.println("节点存在");
            System.out.println(stat);
        }else {
            System.out.println("节点不存在");
        }
    }

    @Test
    public void test8() throws Exception{
        // get /test_node2 watch
        // 构造一个监听对象
        NodeCache nodeCache = new NodeCache(client,"/test_node2");
        // 启动一下监听客户端
        nodeCache.start();
        // 匿名内部类
        // 接口回调 【重要】
        nodeCache.getListenable().addListener(new NodeCacheListener() {
            @Override
            public void nodeChanged() throws Exception {
                System.out.println("不好啦！节点中的值被动了！");
                // 打印变更后的值
                byte[] data = nodeCache.getCurrentData().getData();
                System.out.println("变更后的值是：" + new String(data));
            }
        });
        Thread.sleep(Long.MAX_VALUE); // 跟你敲 99999...是一样的
    }

    @Test
    public void test9() throws Exception {
        // ls /test_node2 watch
        // 构造一个监听对象,监听一个节点下的所有子节点变化
        PathChildrenCache childrenCache = new PathChildrenCache(client,"/test_node2",true);
        // 启动客户端
        childrenCache.start();
        childrenCache.getListenable().addListener(new PathChildrenCacheListener() {
            @Override
            public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
                System.out.println(event.getType());
                switch (event.getType()){
                    case CHILD_ADDED:
                        System.out.println("节点增加了！");
                        System.out.println("节点的位置是：" + event.getData().getPath());
                        System.out.println("节点的值是：" + new String(event.getData().getData()));
                }
            }
        });
        Thread.sleep(99999999999L);
    }
    @After
    public void testEnd() throws Exception{
        client.close();
    }
}
